#include <atomic>
#include <iostream>
#include <memory>

int main()
{
	/// atomic_flag
	{
		std::atomic_flag f = ATOMIC_FLAG_INIT;
		f.clear(std::memory_order_release);
		bool x = f.test_and_set();
	}

	/// atomic<bool>
	{
		std::atomic<bool> b(true);
		b = false;
		bool x = b.load(std::memory_order_acquire);
		b.store(true);
		x = b.exchange(false,std::memory_order_acq_rel);
		bool expected = false;
		while(!b.compare_exchange_weak(expected,true) && !expected);
		b.compare_exchange_strong(expected,true);
		b.compare_exchange_weak(expected,true,std::memory_order_acq_rel,std::memory_order_acquire);
		//b.compare_exchange_weak(expected,true,std::memory_order_acq_rel);
		std::cout << std::boolalpha << b.is_lock_free() << std::endl;
	}

	///atomic<T*>
	{
		class Foo{};
		Foo some_array[5];
		std::atomic<Foo*> p(some_array);
		Foo* x = p.fetch_add(2);
		assert(x==some_array);
		assert(p.load()==&some_array[2]);
		x=(p-=1);
		assert(x==&some_array[1]);
		assert(p.load()==&some_array[1]);
	}

}